/**
    package: learn-go
    filename: mutexRandom
    author: diogo@gmail.com
    time: 2023/3/8 14:21
	description:  先导入用户,再抽奖
**/

/**
*  curl http://localhost:8080/
*  curl --data "users=123,567" http://localhost:8080/import
*  curl http://localhost:8080/lucky
 */

package main

import (
	"fmt"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"math/rand"
	"strings"
	"sync"
	"time"
)

var userList []string // 共享变量读写前后 需要增加 锁的设定 简单方式添加互斥锁
var mu sync.Mutex

type lotteryController struct {
	Ctx iris.Context
}

// 启动一个 iris 应用
func newApp() *iris.Application {
	app := iris.New()
	mvc.New(app.Party("/")).Handle(&lotteryController{})
	return app
}

func main() {
	app := newApp()
	userList = []string{}
	mu = sync.Mutex{}
	err := app.Listen(":8080")
	if err != nil {
		panic(fmt.Sprintf("web server start error: %s\n", err))
		return
	}
}

func (c *lotteryController) Get() string {
	count := len(userList)
	return fmt.Sprintf("当前总共参与抽奖的用户数：%d\n", count)
}

// PostImport POST http://localhost:8090/import
// params : users
func (c *lotteryController) PostImport() string {
	strUsers := c.Ctx.FormValue("users")
	users := strings.Split(strUsers, ",")
	// 批量线程导入时候 发现有多线程的问题 数据统计不正确
	mu.Lock()
	defer mu.Unlock()
	count1 := len(userList)
	for _, u := range users {
		u = strings.TrimSpace(u)
		if len(u) > 0 {
			userList = append(userList, u)
		}
	}
	count2 := len(userList)
	return fmt.Sprintf("当前总共参与抽奖的用户数：%d, 成功导入的用户数：%d\n", count2, count2-count1)
}

// GetLucky GET http://localhost:8090/lucky
func (c *lotteryController) GetLucky() string {
	// 抽奖地方进行锁的判断
	mu.Lock()
	defer mu.Unlock()

	count := len(userList)
	if count > 1 {
		index := rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(int32(count))
		user := userList[index]
		// 需要 删除被挑选过的人 直接可以删除 当前index 下的数据 更好
		userList = append(userList[0:index], userList[index+1:]...)
		return fmt.Sprintf("当前中奖用户：%s, 剩余用户数：%d\n", user, count-1)
	} else if count == 1 {
		user := userList[0]
		return fmt.Sprintf("当前中奖用户：%s, 剩余用户数：%d\n", user, count-1)
	} else {
		return fmt.Sprintf("当前中奖完毕,没有用户参与中奖\n")
	}
}
